home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Scene 96
/
Scene 96 International Edition (Zyklop Software) (Disc 2) (1997).iso
/
misc
/
coding
/
cp2dekit
/
samples
/
binfcach.cpp
< prev
next >
Wrap
C/C++ Source or Header
|
1996-12-29
|
4KB
|
192 lines
//***************************************************************************
//
// this file is (c) '94-'96 Niklas Beisert
//
// this file is part of the cubic player development kit.
// you may only use/modify/spread this file under the terms stated
// in the cubic player development kit accompanying documentation.
//
//***************************************************************************
#include <string.h>
#include "binfile.h"
binfilecache::binfilecache()
{
}
void binfilecache::invalidatebuf()
{
if (dirty)
{
if (fileseekpos!=filebufpos)
f->seek(filebufpos);
bufread=f->write(buffer,bufread);
fileseekpos=filebufpos+bufread;
dirty=0;
}
filebufpos+=bufread;
bufread=0;
bufpos=0;
}
int binfilecache::open(binfile &fil, int len)
{
close();
if (!fil.getmode())
return 0;
f=&fil;
int fmode=f->getmode();
if ((fmode&canread)&&(fmode&canwrite)&&!(fmode&canseek))
return 0;
buffer=new char[len];
if (!buffer)
return 0;
filelen=f->length();
buflen=len;
bufpos=0;
bufread=0;
filepos=0;
dirty=0;
fileseekpos=f->tell();
filebufpos=fileseekpos;
mode=fmode;
return 1;
}
void binfilecache::close()
{
if (mode)
{
invalidatebuf();
delete buffer;
}
binfile::close();
}
long binfilecache::read(void *buf, long len)
{
if (!(mode&canread))
return 0;
int len0=bufread-bufpos;
if (len<len0)
len0=len;
len-=len0;
memcpy(buf,buffer+bufpos,len0);
bufpos+=len0;
filepos=filebufpos+bufpos;
if (!len)
return len0;
if (len<(buflen-bufread))
{
if (fileseekpos!=(filebufpos+bufread))
f->seek(filebufpos+bufread);
int l=f->read(buffer,buflen-bufread);
if (l<len)
len=l;
memcpy((char*)buf+len0,buffer+bufread,len);
bufpos+=len;
bufread+=l;
}
else
{
invalidatebuf();
if (len>=buflen)
{
if (fileseekpos!=filebufpos)
f->seek(filebufpos);
len=f->read((char*)buf+len0,len);
filebufpos+=len;
}
else
{
if (fileseekpos!=filebufpos)
f->seek(filebufpos);
bufread=f->read(buffer,buflen);
if (bufread<len)
len=bufread;
memcpy((char*)buf+len0,buffer,len);
bufpos=len;
}
}
fileseekpos=filebufpos+bufread;
filepos=filebufpos+bufpos;
return len0+len;
}
long binfilecache::write(const void *buf, long len)
{
if (!(mode&canwrite))
return 0;
if (!(mode&canchsize))
if (len>(filelen-filepos))
len=filelen-filepos;
int len0=buflen-bufpos;
if (len<len0)
len0=len;
if (len0)
dirty=1;
len-=len0;
memcpy(buffer+bufpos,buf,len0);
bufpos+=len0;
if (bufpos>bufread)
bufread=bufpos;
filepos=filebufpos+bufpos;
if (filepos>filelen)
filelen=filepos;
if (!len)
return len0;
invalidatebuf();
if (len>=buflen)
{
if (fileseekpos!=filebufpos)
f->seek(filebufpos);
len=f->write((const char *)buf+len0,len);
filebufpos+=len;
fileseekpos=filebufpos;
}
else
{
memcpy(buffer,(const char *)buf+len0,len);
bufread=len;
bufpos=len;
}
filepos=filebufpos+bufpos;
if (filepos>filelen)
filelen=filepos;
return len0+len;
}
long binfilecache::seek(long pos)
{
if (!(mode&canseek))
return filepos;
if (pos<0)
pos=0;
if (pos>filelen)
pos=filelen;
if ((pos>=filebufpos)&&(pos<=(filebufpos+bufread)))
bufpos=pos-filebufpos;
else
{
invalidatebuf();
filebufpos=pos;
}
filepos=pos;
return filepos;
}
long binfilecache::chsize(long pos)
{
if (!(mode&canchsize))
return filelen;
invalidatebuf();
filelen=f->chsize(pos);
filepos=filebufpos=f->tell();
return filelen;
}